package cn.tedu._053mvcweibo.controller;

import cn.tedu._053mvcweibo.common.response.JsonResult;
import cn.tedu._053mvcweibo.common.response.StatusCode;
import cn.tedu._053mvcweibo.mapper.UserMapper;
import cn.tedu._053mvcweibo.pojo.dto.UserLoginDTO;
import cn.tedu._053mvcweibo.pojo.dto.UserRegDTO;
import cn.tedu._053mvcweibo.pojo.entity.User;
import cn.tedu._053mvcweibo.pojo.vo.UserVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpSession;
import java.util.Date;

/**
 * RestController注解：复合注解(Controller和ResponseBody注解)
 * Api(tags="")注解：Knife4j中显示模块名
 */
@Slf4j
@RestController
@Api(tags = "01.用户模块")
@RequestMapping("/v1/users/")
public class UserController {

    // 自动装配
    @Autowired(required = false)
    private UserMapper userMapper;

    /**1.注册功能
     * RequestBody注解：客户端 --> 服务端, 将请求体中JSON格式的数据解析为对应的JAVA对象
     * ResponseBody注解：服务端 --> 客户端, 将服务端需要返回的JAVA对象转为JSON格式的字符串
     * ApiOperation注解：在Knife4j页面中,指定显示的接口名称
     */
    @PostMapping("reg")
    @ApiOperation(value = "注册功能")
    public JsonResult reg(@RequestBody @Validated UserRegDTO userRegDTO){
        /*
            只要添加了@Slf4j注解,就会创建一个 log 对象
            log.trace("xxx")
            log.debug("xxx")
            log.info("xxx")
            log.warn("xxx")
            log.error("xxx")
         */
        log.debug("userRegDTO = " + userRegDTO);
        /*
            1.数据表查询用户是否被占用:username
            2.被占用: return 2;
            3.未被占用: 用户数据存入数据表, return 1;
         */
        // 是否被占用
        UserVO userVO = userMapper.selectByUsername(userRegDTO.getUsername());
        if (userVO != null){//用户名被占用
            return new JsonResult(StatusCode.USERNAME_ALREADY_EXISTS);
        }
        //未被占用,插入数据表
        User user = new User();
        BeanUtils.copyProperties(userRegDTO, user);
        user.setCreated(new Date());
        userMapper.insertUser(user);

        //return new JsonResult(StatusCode.OPERATION_SUCCESS); //注册成功
        return JsonResult.ok();
    }

    /**
     * 登录功能
     * 1.@return 1-登录成功 2-密码错误 3-用户名错误
     *   一定要注意添加 RequestBody 注解
     * 2.ApiIgnore注解：加在参数上,指定Knife4j需要忽略的参数(不在页面中显示给客户端)
     */
    @PostMapping("login")
    @ApiOperation(value = "登录功能")
    public JsonResult login(@RequestBody UserLoginDTO userLoginDTO, @ApiIgnore HttpSession session){
        log.debug("userLoginDTO = " + userLoginDTO);
        /*
            1.根据username查询数据
            2.查到数据: 比较密码
            3.未查到数据: 用户名错
         */
        //不需要额外定义Mapper接口方法,复用注册功能的接口方法即可
        UserVO userVO = userMapper.selectByUsername(userLoginDTO.getUsername());
        if (userVO == null){//用户名错误
            return new JsonResult(StatusCode.USERNAME_ERROR);
        }
        if (userVO.getPassword().equals(userLoginDTO.getPassword())){
            /*
            登录成功后,将该用户的相关信息保存到session会话中(服务器内存中)
            1.存：session.setAttribute(String, Object)
            2.取：session.getAttribute(String)
            3.删：session.removeAttribute(String)
             */
            session.setAttribute("user", userVO);
            System.out.println(session.getAttribute("user"));
            return new JsonResult(StatusCode.LOGIN_SUCCESS);//登录成功
        }
        return new JsonResult(StatusCode.PASSWORD_ERROR);//密码错误
    }

    /**
     * 获取当前用户登录状态：session.getAttribute(String)
     */
    @GetMapping("currentUser")
    @ApiOperation(value = "获取当前用户功能")
    public JsonResult currentUser(@ApiIgnore HttpSession session){
        UserVO userVO = (UserVO) session.getAttribute("user");
        //输出日志信息DEBUG
        log.debug("userVO = " + userVO);

        //return new JsonResult(StatusCode.OPERATION_SUCCESS, userVO);
        return JsonResult.ok(userVO);
    }

    /**退出登录功能*/
    @GetMapping("logout")
    @ApiOperation(value = "退出登录功能")
    public void logout(@ApiIgnore HttpSession session){
        // 在服务器内存中删除唯一标识
        session.removeAttribute("user");
        // "" + xxx,将获取的结果转为字符串输出
        log.debug("" + session.getAttribute("user"));
    }
}








